package sys

import (
	"ginweb-admin/commons/base/api"
	"ginweb-admin/commons/jwtgo"
	"ginweb-admin/commons/response"
	"ginweb-admin/model/context"
	"ginweb-admin/model/entity/sys"
	"ginweb-admin/utils"
	"github.com/gin-gonic/gin"
	"github.com/gookit/validate"
	"strconv"
	"strings"
	"time"
)

type SysRoleApiApi struct {
	api.BaseApi
}

// 保存用户角色对应的权限
func (api *SysRoleApiApi) SaveRoleApi(c *gin.Context) {
	// 准备接收用户传递的参数上下文
	sysRoleApiContext := context.SysRoleApiContext{}
	// 绑定参数
	err := c.ShouldBindJSON(&sysRoleApiContext)
	if err != nil {
		response.FailWithError(err, c)
		return
	}
	// 参数校验
	validation := validate.Struct(sysRoleApiContext)
	if !validation.Validate() {
		response.FailWithValidatorData(validation, c)
		return
	}

	// 把获取到的权限进行分割
	// 把获取到的菜单进行分割
	apiIds := strings.Split(sysRoleApiContext.ApiIds, ",")
	// 准备切片菜单容器
	sysRoleApis := []*sys.SysRoleAPi{}
	// 遍历获取到菜单id
	for _, apiId := range apiIds {
		// 准备单个容器，用来存放单个菜单数据
		sysRoleApi := sys.SysRoleAPi{}
		sysRoleApi.RoleId = sysRoleApiContext.RoleId
		sysRoleApi.ApiId = api.StringToUnit(apiId)
		// 把单个数据容器存放到切片容器中
		sysRoleApis = append(sysRoleApis, &sysRoleApi)
	}

	// 保存角色菜单的方法
	if err := sysRoleApiService.SaveRoleApis(sysRoleApiContext.RoleId, sysRoleApis); err != nil {
		response.FailWithMessage("创建失败！", c)
		return
	}
	// 如果保存成功，就返回创建创建成功
	response.Ok("创建成功", c)
}

// 查询用户角色对应的菜单
func (api *SysRoleApiApi) SelectRoleApis(c *gin.Context) {
	roleIdStr := c.Query("roleId")
	roleId := api.StringToUnit(roleIdStr)
	if roleId == 0 {
		response.FailWithMessage("请选择一个角色操作", c)
		return
	}
	roles, err := sysRoleApiService.SelectRoleApis(roleId)
	if err != nil {
		response.FailWithMessage("查询失败！", c)
		return
	}
	response.Ok(roles, c)
}

// 角色切换更换菜单
func (api *SysRoleApiApi) ChangeRoleIdMenus(c *gin.Context) {
	// 获取角色id
	roleIdStr := c.Query("roleId")
	roleId := api.StringToUnit(roleIdStr)
	if roleId == 0 {
		response.FailWithMessage("请选择一个角色操作", c)
		return
	}

	role, _ := sysRoleService.GetById(roleId)
	// 根据用户角色id查询菜单信息
	roleMenus, _ := sysRoleMenuService.SelectRoleMenus(roleId)
	// 根据用户角色id查询用户的角色的权限
	permissions, _ := sysRoleApiService.SelectRoleApis(roleId)
	// 改变角色，切换token
	api.ChangeRoleToken(c, role)
	// 查询返回
	response.Ok(map[string]any{"roleMenus": sysMenuService.Tree(roleMenus, 0), "permissions": permissions}, c)
}

// 角色切换的时候重新生成token
func (api *SysRoleApiApi) ChangeRoleToken(c *gin.Context, role *sys.SysRole) {
	// 生成jwt的对象
	myJwt := jwtgo.NewJWT()
	token := c.Request.Header.Get("Authorization")
	// 把token重新生成在返回
	claims := jwtgo.GetUserInfo(c)
	claims.RoleCode = role.RoleCode
	claims.RoleId = role.ID
	epTime, _ := utils.ParseDuration("7d")
	// 用当前时间+eptime 就是 新的token过期时间
	claims.ExpiresAt = time.Now().Add(epTime).Unix()
	// 生成新的token
	newToken, _ := myJwt.CreateTokenByOldToken(token, *claims)
	// 输出给浏览器----request--header----给服务端
	// 输出给浏览器----response--header---给浏览器
	c.Header("new-authorization", newToken)
	c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt, 10))
}
